Removed the unref_fn field. Now all memory management of the buffer is
authorFederico Mena Quintero <federico@redhat.com>
Wed, 20 Oct 1999 21:20:49 +0000 (21:20 +0000)
committerArturo Espinosa <unammx@src.gnome.org>
Wed, 20 Oct 1999 21:20:49 +0000 (21:20 +0000)
1999-10-20  Federico Mena Quintero  <federico@redhat.com>

* src/gdk-pixbuf.h (GdkPixbuf): Removed the unref_fn field.  Now
all memory management of the buffer is done by libart.

* src/gdk-pixbuf.c (gdk_pixbuf_unref): Do destruction here.
Removed gdk_pixbuf_destroy, gdk_pixbuf_duplicate.

* src/gdk-pixbuf-data.c (gdk_pixbuf_new_from_data): Implemented in
terms of the libart functions.  Removed the old code.

* src/gdk-pixbuf-io.c (image_handler_load): Removed the save
symbols.  Saving will not be implemented in GdkPixbuf.

* src/io-gif.c: Removed the saving stub.
(image_load): Fixed memory management to fail gracefully if we run
out of memory while loading the image.  Close the gif file when we
are done.  This still needs more error handling for the DGif
functions.

* src/io-jpeg.c (image_load): Some robustness fixes.

* src/io-png.c: Removed the saving stuff.
(image_load): Some memory management fixes.

* src/io-tiff.c (image_load): Ditto.

* src/io-xpm.c (pixbuf_create_from_xpm): Ditto.

13 files changed:
demos/testpixbuf.c
gdk-pixbuf/ChangeLog
gdk-pixbuf/Makefile.am
gdk-pixbuf/gdk-pixbuf-data.c
gdk-pixbuf/gdk-pixbuf-io.c
gdk-pixbuf/gdk-pixbuf-xform.c [new file with mode: 0644]
gdk-pixbuf/gdk-pixbuf.c
gdk-pixbuf/gdk-pixbuf.h
gdk-pixbuf/io-gif.c
gdk-pixbuf/io-jpeg.c
gdk-pixbuf/io-png.c
gdk-pixbuf/io-tiff.c
gdk-pixbuf/io-xpm.c

index e9b984ea16fe9076dfc496536b70c366d293671c..96c20bd63e476617deee92636bdd0d24b1778581 100644 (file)
@@ -185,7 +185,6 @@ static void
 expose_func (GtkWidget *drawing_area, GdkEventExpose *event, gpointer data)
 {
        GdkPixbuf *pixbuf;
-       gint x1, y1, x2, y2;
 
        pixbuf = (GdkPixbuf *)gtk_object_get_data(GTK_OBJECT(drawing_area), "pixbuf");
 
@@ -217,16 +216,17 @@ expose_func (GtkWidget *drawing_area, GdkEventExpose *event, gpointer data)
 static void
 config_func (GtkWidget *drawing_area, GdkEventConfigure *event, gpointer data)
 {
-       GdkPixbuf *pixbuf, *spb;
+       GdkPixbuf *pixbuf;
     
        pixbuf = (GdkPixbuf *)gtk_object_get_data(GTK_OBJECT(drawing_area), "pixbuf");
 
        g_print("X:%d Y:%d\n", event->width, event->height);
 
+#if 0
        if (((event->width) != (pixbuf->art_pixbuf->width)) ||
            ((event->height) != (pixbuf->art_pixbuf->height))) 
                gdk_pixbuf_scale(pixbuf, event->width, event->height);
-
+#endif
 }
 
 static void
@@ -299,18 +299,18 @@ main (int argc, char **argv)
 
        i = 1;
        if (argc == 1) {
-               pixbuf = gdk_pixbuf_load_image_from_rgb_d(default_image,
-                                                         DEFAULT_WIDTH,
-                                                         DEFAULT_HEIGHT);
-               if (pixbuf) {
-                       new_testrgb_window (pixbuf);
-                       found_valid = TRUE;
-               }
+               pixbuf = gdk_pixbuf_new_from_data ((guchar *) default_image, ART_PIX_RGB, FALSE,
+                                                  DEFAULT_WIDTH, DEFAULT_HEIGHT, DEFAULT_WIDTH * 3,
+                                                  NULL, NULL);
+               new_testrgb_window (pixbuf);
+               found_valid = TRUE;
        } else {
                for (i = 1; i < argc; i++) {
-                       pixbuf = gdk_pixbuf_load_image (argv[i]);
+                       pixbuf = gdk_pixbuf_new_from_file (argv[i]);
+#if 0
                        pixbuf = gdk_pixbuf_rotate(pixbuf, 10.0);
-                 
+#endif
+
                        if (pixbuf) {
                                new_testrgb_window (pixbuf);
                                found_valid = TRUE;
index 4fef786ff2836484675b9a862c3ed4ef77936358..16885f9934464cb1c5c19289ce21837cc4e46983 100644 (file)
@@ -1,3 +1,32 @@
+1999-10-20  Federico Mena Quintero  <federico@redhat.com>
+
+       * src/gdk-pixbuf.h (GdkPixbuf): Removed the unref_fn field.  Now
+       all memory management of the buffer is done by libart.
+
+       * src/gdk-pixbuf.c (gdk_pixbuf_unref): Do destruction here.
+       Removed gdk_pixbuf_destroy, gdk_pixbuf_duplicate.
+
+       * src/gdk-pixbuf-data.c (gdk_pixbuf_new_from_data): Implemented in
+       terms of the libart functions.  Removed the old code.
+
+       * src/gdk-pixbuf-io.c (image_handler_load): Removed the save
+       symbols.  Saving will not be implemented in GdkPixbuf.
+
+       * src/io-gif.c: Removed the saving stub.
+       (image_load): Fixed memory management to fail gracefully if we run
+       out of memory while loading the image.  Close the gif file when we
+       are done.  This still needs more error handling for the DGif
+       functions.
+
+       * src/io-jpeg.c (image_load): Some robustness fixes.
+
+       * src/io-png.c: Removed the saving stuff.
+       (image_load): Some memory management fixes.
+
+       * src/io-tiff.c (image_load): Ditto.
+
+       * src/io-xpm.c (pixbuf_create_from_xpm): Ditto.
+
 1999-10-18  Havoc Pennington  <hp@pobox.com>
 
        * subautogen.sh: New name for macros/autogen.sh
@@ -6,7 +35,9 @@
 
 1999-10-18  Federico Mena Quintero  <federico@redhat.com>
 
-       * src/*: Reindented to use the GNOME Indentation.
+       * src/*: Reindented to use the GNOME Indentation.  Renamed
+       GdkPixBuf to GdkPixbuf, for consistency with the function names
+       (and it is also easier to type) :-)
 
 1999-10-18  Havoc Pennington  <hp@pobox.com>
 
index 89bab3e840fa1cb49d87ff0a59351bfc4c27cb48..b9e783cfa6562ba45f170767cf2b818f255db957 100644 (file)
@@ -1,4 +1,3 @@
-
 lib_LTLIBRARIES =              \
        libgdk_pixbuf.la
 
@@ -49,8 +48,7 @@ libgdk_pixbuf_la_SOURCES =    \
        gdk-pixbuf-data.c
 
 libgdk_pixbufinclude_HEADERS = \
-       gdk-pixbuf.h            \
-       gdk-pixbuf-io.h
+       gdk-pixbuf.h
 
 #
 # The PNG plugin.
index b14244b4616e6116f2ad0a13971e2d0d11fc262d..0919e94a92d7c35f289545f68cca565de6769eb0 100644 (file)
@@ -1,49 +1,69 @@
-/*
- * gdk-pixbuf-data.c: Code to load images into GdkPixbufs from constant data
+/* GdkPixbuf library - Image creation from in-memory buffers
  *
- * Author:
- *    Michael Fulbright (drmike@redhat.com)
- *    Copyright (C) 1999 Red Hat, Inc.
+ * Copyright (C) 1999 The Free Software Foundation
+ *
+ * Author: Federico Mena-Quintero <federico@gimp.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
  */
 
 #include <config.h>
-#include <stdio.h>
-#include <string.h>
-#include <glib.h>
-
 #include "gdk-pixbuf.h"
 
-/* This function does all the work. */
+\f
 
-static GdkPixbuf *
-_pixbuf_create_from_rgb_d(unsigned char *data, int w, int h)
+/**
+ * gdk_pixbuf_new_from_data:
+ * @data: Image data in 8-bit/sample packed format.
+ * @format: Color format used for the data.
+ * @has_alpha: Whether the data has an opacity channel.
+ * @width: Width of the image in pixels.
+ * @height: Height of the image in pixels.
+ * @rowstride: Distance in bytes between rows.
+ * @dfunc: Function used to free the data when the pixbuf's reference count
+ * drops to zero, or NULL if the data should not be freed.
+ * @dfunc_data: Closure data to pass to the destroy notification function.
+ * 
+ * Creates a new &GdkPixbuf out of in-memory RGB data.
+ * 
+ * Return value: A newly-created &GdkPixbuf structure with a reference count of
+ * 1.
+ **/
+GdkPixbuf *
+gdk_pixbuf_new_from_data (guchar *data, ArtPixFormat format, gboolean has_alpha,
+                         int width, int height, int rowstride,
+                         ArtDestroyNotify dfunc, gpointer dfunc_data)
 {
-       GdkPixbuf *pixbuf;
        ArtPixBuf *art_pixbuf;
-       art_u8 *pixels;
-
-       pixels = art_alloc (w*h*3);
-       if (!pixels) {
-               g_warning ("RGBD: Cannot alloc ArtBuf");
-               return NULL;
-       }
 
-       memcpy (pixels, data, w*h*3);
+       /* Only 8-bit/sample RGB buffers are supported for now */
 
-       art_pixbuf = art_pixbuf_new_rgb (pixels, w, h, (w*3));
-       pixbuf = gdk_pixbuf_new (art_pixbuf, NULL);
-
-       if (!pixbuf)
-               art_free (pixels);
-
-       return pixbuf;
-}
+       g_return_val_if_fail (data != NULL, NULL);
+       g_return_val_if_fail (format == ART_PIX_RGB, NULL);
+       g_return_val_if_fail (width > 0, NULL);
+       g_return_val_if_fail (height > 0, NULL);
 
+       if (has_alpha)
+               art_pixbuf = art_pixbuf_new_rgba_dnotify (data, width, height, rowstride,
+                                                         dfunc_data, dfunc);
+       else
+               art_pixbuf = art_pixbuf_new_rgb_dnotify (data, width, height, rowstride,
+                                                        dfunc_data, dfunc);
 
-GdkPixbuf *
-gdk_pixbuf_load_image_from_rgb_d (unsigned char *data, int rgb_width, int rgb_height)
-{
-       g_return_val_if_fail (data != NULL, NULL);
+       g_assert (art_pixbuf != NULL);
 
-       return _pixbuf_create_from_rgb_d(data, rgb_width, rgb_height);
+       return gdk_pixbuf_new_from_art_pixbuf (art_pixbuf);
 }
index a1400feba4484ab887bd5862620194fef80a706d..6e873a53dd09ec3663dab1218583233811d4b65b 100644 (file)
@@ -1,19 +1,36 @@
-/*
- * gdk-pixbuf-io.c: Code to load images into GdkPixbufs
+/* GdkPixbuf library - Main loading interface.
  *
- * Author:
- *    Miguel de Icaza (miguel@gnu.org)
+ * Copyright (C) 1999 The Free Software Foundation
+ *
+ * Authors: Miguel de Icaza <miguel@gnu.org>
+ *          Federico Mena-Quintero <federico@gimp.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
  */
 
 #include <config.h>
 #include <stdio.h>
 #include <string.h>
-#include <glib.h>
 #include <gmodule.h>
 #include "gdk-pixbuf.h"
 
+\f
+
 static gboolean
-pixbuf_check_png (unsigned char *buffer, int size)
+pixbuf_check_png (guchar *buffer, int size)
 {
        if (size < 28)
                return FALSE;
@@ -32,7 +49,7 @@ pixbuf_check_png (unsigned char *buffer, int size)
 }
 
 static gboolean
-pixbuf_check_jpeg (unsigned char *buffer, int size)
+pixbuf_check_jpeg (guchar *buffer, int size)
 {
        if (size < 10)
                return FALSE;
@@ -44,7 +61,7 @@ pixbuf_check_jpeg (unsigned char *buffer, int size)
 }
 
 static gboolean
-pixbuf_check_tiff (unsigned char *buffer, int size)
+pixbuf_check_tiff (guchar *buffer, int size)
 {
        if (size < 10)
                return FALSE;
@@ -65,7 +82,7 @@ pixbuf_check_tiff (unsigned char *buffer, int size)
 }
 
 static gboolean
-pixbuf_check_gif (unsigned char *buffer, int size)
+pixbuf_check_gif (guchar *buffer, int size)
 {
        if (size < 20)
                return FALSE;
@@ -77,7 +94,7 @@ pixbuf_check_gif (unsigned char *buffer, int size)
 }
 
 static gboolean
-pixbuf_check_xpm (unsigned char *buffer, int size)
+pixbuf_check_xpm (guchar *buffer, int size)
 {
        if (size < 20)
                return FALSE;
@@ -89,7 +106,7 @@ pixbuf_check_xpm (unsigned char *buffer, int size)
 }
 
 static gboolean
-pixbuf_check_bmp (unsigned char *buffer, int size)
+pixbuf_check_bmp (guchar *buffer, int size)
 {
        if (size < 20)
                return FALSE;
@@ -101,7 +118,7 @@ pixbuf_check_bmp (unsigned char *buffer, int size)
 }
 
 static gboolean
-pixbuf_check_ppm (unsigned char *buffer, int size)
+pixbuf_check_ppm (guchar *buffer, int size)
 {
        if (size < 20)
                return FALSE;
@@ -119,20 +136,21 @@ pixbuf_check_ppm (unsigned char *buffer, int size)
 }
 
 static struct {
-       char      *module_name;
-       gboolean   (*format_check)(unsigned char *buffer, int size);
-       GModule   *module;
-       GdkPixbuf *(*load)(FILE *f);
-       int        (*save)(GdkPixbuf *p, FILE *f, ...);
+       char *module_name;
+       gboolean (* format_check) (guchar *buffer, int size);
+       GModule *module;
+       GdkPixbuf *(* load) (FILE *f);
 } file_formats [] = {
-       { "png",  pixbuf_check_png,  NULL, NULL, NULL },
-       { "jpeg", pixbuf_check_jpeg, NULL, NULL, NULL },
-       { "tiff", pixbuf_check_tiff, NULL, NULL, NULL },
-       { "gif",  pixbuf_check_gif,  NULL, NULL, NULL },
-       { "xpm",  pixbuf_check_xpm,  NULL, NULL, NULL },
-/*     { "bmp",  pixbuf_check_bmp,  NULL, NULL, NULL },
-       { "ppm",  pixbuf_check_ppm,  NULL, NULL, NULL },*/
-       { NULL, NULL, NULL, NULL, NULL }
+       { "png",  pixbuf_check_png,  NULL, NULL },
+       { "jpeg", pixbuf_check_jpeg, NULL, NULL },
+       { "tiff", pixbuf_check_tiff, NULL, NULL },
+       { "gif",  pixbuf_check_gif,  NULL, NULL },
+       { "xpm",  pixbuf_check_xpm,  NULL, NULL },
+#if 0
+       { "bmp",  pixbuf_check_bmp,  NULL, NULL },
+       { "ppm",  pixbuf_check_ppm,  NULL, NULL },
+#endif
+       { NULL, NULL, NULL, NULL }
 };
 
 static void
@@ -141,10 +159,9 @@ image_handler_load (int idx)
        char *module_name;
        char *path;
        GModule *module;
-       void *load_sym, *save_sym;
+       void *load_sym;
 
-       module_name = g_strconcat ("pixbuf-",
-                                  file_formats [idx].module_name, NULL);
+       module_name = g_strconcat ("pixbuf-", file_formats [idx].module_name, NULL);
        path = g_module_build_path (PIXBUF_LIBDIR, module_name);
        g_free (module_name);
 
@@ -158,22 +175,22 @@ image_handler_load (int idx)
 
        if (g_module_symbol (module, "image_load", &load_sym))
                file_formats [idx].load = load_sym;
-
-       if (g_module_symbol (module, "image_save", &save_sym))
-               file_formats [idx].save = save_sym;
 }
 
+\f
+
 GdkPixbuf *
-gdk_pixbuf_load_image (const char *file)
+gdk_pixbuf_new_from_file (const char *filename)
 {
        GdkPixbuf *pixbuf;
        gint n, i;
        FILE *f;
        char buffer [128];
 
-       f = fopen (file, "r");
+       f = fopen (filename, "r");
        if (!f)
                return NULL;
+
        n = fread (&buffer, 1, sizeof (buffer), f);
 
        if (n == 0) {
@@ -182,7 +199,7 @@ gdk_pixbuf_load_image (const char *file)
        }
 
        for (i = 0; file_formats [i].module_name; i++) {
-               if ((*file_formats [i].format_check)(buffer, n)) {
+               if ((* file_formats [i].format_check) (buffer, n)) {
                        if (!file_formats [i].load)
                                image_handler_load (i);
 
@@ -191,15 +208,18 @@ gdk_pixbuf_load_image (const char *file)
                                return NULL;
                        }
 
-                       fseek(f, 0, SEEK_SET);
-                       pixbuf = (*file_formats [i].load)(f);
+                       fseek (f, 0, SEEK_SET);
+                       pixbuf = (* file_formats [i].load) (f);
                        fclose (f);
-                       g_assert (pixbuf->ref_count != 0);
+
+                       if (pixbuf)
+                               g_assert (pixbuf->ref_count != 0);
+
                        return pixbuf;
                }
        }
 
        fclose (f);
-       g_warning ("Unable to find handler for file: %s", file);
+       g_warning ("Unable to find handler for file: %s", filename);
        return NULL;
 }
diff --git a/gdk-pixbuf/gdk-pixbuf-xform.c b/gdk-pixbuf/gdk-pixbuf-xform.c
new file mode 100644 (file)
index 0000000..1e2eabe
--- /dev/null
@@ -0,0 +1,95 @@
+GdkPixbuf *
+gdk_pixbuf_scale (const GdkPixbuf *pixbuf, gint w, gint h)
+{
+       art_u8 *pixels;
+       gint rowstride;
+       double affine[6];
+       ArtAlphaGamma *alphagamma;
+       ArtPixBuf *art_pixbuf = NULL;
+       GdkPixbuf *copy = NULL;
+
+       alphagamma = NULL;
+
+       affine[1] = affine[2] = affine[4] = affine[5] = 0;
+
+       affine[0] = w / (double)(pixbuf->art_pixbuf->width);
+       affine[3] = h / (double)(pixbuf->art_pixbuf->height);
+
+       /* rowstride = w * pixbuf->art_pixbuf->n_channels; */
+       rowstride = w * 3;
+
+       pixels = art_alloc (h * rowstride);
+       art_rgb_pixbuf_affine (pixels, 0, 0, w, h, rowstride,
+                              pixbuf->art_pixbuf,
+                              affine, ART_FILTER_NEAREST, alphagamma);
+
+       if (pixbuf->art_pixbuf->has_alpha)
+               /* should be rgba */
+               art_pixbuf = art_pixbuf_new_rgb(pixels, w, h, rowstride);
+       else
+               art_pixbuf = art_pixbuf_new_rgb(pixels, w, h, rowstride);
+
+       copy = gdk_pixbuf_new (art_pixbuf, NULL);
+
+       if (!copy)
+               art_free (pixels);
+
+       return copy;
+}
+
+GdkPixbuf *
+gdk_pixbuf_rotate (GdkPixbuf *pixbuf, gdouble angle)
+{
+       art_u8 *pixels;
+       gint rowstride, w, h;
+       gdouble rad;
+       double rot[6], trans[6], affine[6];
+       ArtAlphaGamma *alphagamma = NULL;
+       ArtPixBuf *art_pixbuf = NULL;
+
+       w = pixbuf->art_pixbuf->width;
+       h = pixbuf->art_pixbuf->height;
+
+       rad = (M_PI * angle / 180.0);
+
+       rot[0] = cos(rad);
+       rot[1] = sin(rad);
+       rot[2] = -sin(rad);
+       rot[3] = cos(rad);
+       rot[4] = rot[5] = 0;
+
+       trans[0] = trans[3] = 1;
+       trans[1] = trans[2] = 0;
+       trans[4] = -(double)w / 2.0;
+       trans[5] = -(double)h / 2.0;
+
+       art_affine_multiply(rot, trans, rot);
+
+       trans[0] = trans[3] = 1;
+       trans[1] = trans[2] = 0;
+       trans[4] = (double)w / 2.0;
+       trans[5] = (double)h / 2.0;
+
+       art_affine_multiply(affine, rot, trans);
+
+       g_print("Affine: %e %e %e %e %e %e\n", affine[0], affine[1], affine[2],
+               affine[3], affine[4], affine[5]);
+
+       /* rowstride = w * pixbuf->art_pixbuf->n_channels; */
+       rowstride = w * 3;
+
+       pixels = art_alloc (h * rowstride);
+       art_rgb_pixbuf_affine (pixels, 0, 0, w, h, rowstride,
+                              pixbuf->art_pixbuf,
+                              affine, ART_FILTER_NEAREST, alphagamma);
+       if (pixbuf->art_pixbuf->has_alpha)
+               /* should be rgba */
+               art_pixbuf = art_pixbuf_new_rgb(pixels, w, h, rowstride);
+       else
+               art_pixbuf = art_pixbuf_new_rgb(pixels, w, h, rowstride);
+
+       art_pixbuf_free (pixbuf->art_pixbuf);
+       pixbuf->art_pixbuf = art_pixbuf;
+
+       return pixbuf;
+}
index 231f115a9716d3ffafe421bfaaed7f43b2128533..a35ac01c463747a583ad8cd50edf12d350418775 100644 (file)
@@ -1,11 +1,10 @@
-/* GdkPixbuf library
+/* GdkPixbuf library - Basic memory management
  *
  * Copyright (C) 1999 The Free Software Foundation
  *
  * Authors: Mark Crichton <crichton@gimp.org>
  *          Miguel de Icaza <miguel@gnu.org>
  *          Federico Mena-Quintero <federico@gimp.org>
- *          Carsten Haitzler <raster@rasterman.com>
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public
@@ -25,7 +24,6 @@
 
 #include <config.h>
 #include <math.h>
-#include <glib.h>
 #include <libart_lgpl/art_misc.h>
 #include <libart_lgpl/art_affine.h>
 #include <libart_lgpl/art_pixbuf.h>
 
 \f
 
-void
-gdk_pixbuf_destroy (GdkPixbuf *pixbuf)
-{
-       art_pixbuf_free (pixbuf->art_pixbuf);
-       pixbuf->art_pixbuf = NULL;
-       g_free (pixbuf);
-}
-
-GdkPixbuf *
-gdk_pixbuf_new (ArtPixBuf *art_pixbuf, GdkPixbufUnrefFunc *unref_fn)
-{
-       GdkPixbuf *pixbuf;
-
-       if (!art_pixbuf)
-               return NULL;
-
-       pixbuf = g_new (GdkPixbuf, 1);
-       pixbuf->ref_count = 1;
-       pixbuf->unref_fn = unref_fn;
-       pixbuf->art_pixbuf = art_pixbuf;
-
-       return pixbuf;
-}
+/* Reference counting */
 
+/**
+ * gdk_pixbuf_ref:
+ * @pixbuf: A pixbuf.
+ *
+ * Adds a reference to a pixbuf.  It must be released afterwards using
+ * gdk_pixbuf_unref().
+ **/
 void
 gdk_pixbuf_ref (GdkPixbuf *pixbuf)
 {
@@ -68,6 +51,13 @@ gdk_pixbuf_ref (GdkPixbuf *pixbuf)
        pixbuf->ref_count++;
 }
 
+/**
+ * gdk_pixbuf_unref:
+ * @pixbuf: A pixbuf.
+ *
+ * Removes a reference from a pixbuf.  It will be destroyed when the reference
+ * count drops to zero.
+ **/
 void
 gdk_pixbuf_unref (GdkPixbuf *pixbuf)
 {
@@ -76,113 +66,35 @@ gdk_pixbuf_unref (GdkPixbuf *pixbuf)
 
        pixbuf->ref_count--;
 
-       if (pixbuf->ref_count == 0)
-               gdk_pixbuf_destroy (pixbuf);
+       if (pixbuf->ref_count == 0) {
+               art_pixbuf_free (pixbuf->art_pixbuf);
+               pixbuf->art_pixbuf = NULL;
+               g_free (pixbuf);
+       }
 }
 
-GdkPixbuf *
-gdk_pixbuf_scale (const GdkPixbuf *pixbuf, gint w, gint h)
-{
-       art_u8 *pixels;
-       gint rowstride;
-       double affine[6];
-       ArtAlphaGamma *alphagamma;
-       ArtPixBuf *art_pixbuf = NULL;
-       GdkPixbuf *copy = NULL;
-
-       alphagamma = NULL;
-
-       affine[1] = affine[2] = affine[4] = affine[5] = 0;
-
-       affine[0] = w / (double)(pixbuf->art_pixbuf->width);
-       affine[3] = h / (double)(pixbuf->art_pixbuf->height);
-
-       /* rowstride = w * pixbuf->art_pixbuf->n_channels; */
-       rowstride = w * 3;
-
-       pixels = art_alloc (h * rowstride);
-       art_rgb_pixbuf_affine (pixels, 0, 0, w, h, rowstride,
-                              pixbuf->art_pixbuf,
-                              affine, ART_FILTER_NEAREST, alphagamma);
-
-       if (pixbuf->art_pixbuf->has_alpha)
-               /* should be rgba */
-               art_pixbuf = art_pixbuf_new_rgb(pixels, w, h, rowstride);
-       else
-               art_pixbuf = art_pixbuf_new_rgb(pixels, w, h, rowstride);
-
-       copy = gdk_pixbuf_new (art_pixbuf, NULL);
-
-       if (!copy)
-               art_free (pixels);
-
-       return copy;
-}
-
-GdkPixbuf *
-gdk_pixbuf_duplicate (const GdkPixbuf *pixbuf)
-{
-       GdkPixbuf *copy  = g_new (GdkPixbuf, 1);
-
-       copy->ref_count  = 1;
-       copy->unref_fn   = pixbuf->unref_fn;
-       copy->art_pixbuf = art_pixbuf_duplicate (pixbuf->art_pixbuf);
+\f
 
-       return copy;
-}
+/* Wrap a libart pixbuf */
 
+/**
+ * gdk_pixbuf_new_from_art_pixbuf:
+ * @art_pixbuf: A libart pixbuf.
+ *
+ * Creates a &GdkPixbuf by wrapping a libart pixbuf.
+ *
+ * Return value: A newly-created &GdkPixbuf structure with a reference count of
+ * 1.
+ **/
 GdkPixbuf *
-gdk_pixbuf_rotate (GdkPixbuf *pixbuf, gdouble angle)
+gdk_pixbuf_new_from_art_pixbuf (ArtPixBuf *art_pixbuf)
 {
-       art_u8 *pixels;
-       gint rowstride, w, h;
-       gdouble rad;
-       double rot[6], trans[6], affine[6];
-       ArtAlphaGamma *alphagamma = NULL;
-       ArtPixBuf *art_pixbuf = NULL;
-
-       w = pixbuf->art_pixbuf->width;
-       h = pixbuf->art_pixbuf->height;
-
-       rad = (M_PI * angle / 180.0);
-
-       rot[0] = cos(rad);
-       rot[1] = sin(rad);
-       rot[2] = -sin(rad);
-       rot[3] = cos(rad);
-       rot[4] = rot[5] = 0;
-
-       trans[0] = trans[3] = 1;
-       trans[1] = trans[2] = 0;
-       trans[4] = -(double)w / 2.0;
-       trans[5] = -(double)h / 2.0;
-
-       art_affine_multiply(rot, trans, rot);
-
-       trans[0] = trans[3] = 1;
-       trans[1] = trans[2] = 0;
-       trans[4] = (double)w / 2.0;
-       trans[5] = (double)h / 2.0;
-
-       art_affine_multiply(affine, rot, trans);
-
-       g_print("Affine: %e %e %e %e %e %e\n", affine[0], affine[1], affine[2],
-               affine[3], affine[4], affine[5]);
-
-       /* rowstride = w * pixbuf->art_pixbuf->n_channels; */
-       rowstride = w * 3;
+       GdkPixbuf *pixbuf;
 
-       pixels = art_alloc (h * rowstride);
-       art_rgb_pixbuf_affine (pixels, 0, 0, w, h, rowstride,
-                              pixbuf->art_pixbuf,
-                              affine, ART_FILTER_NEAREST, alphagamma);
-       if (pixbuf->art_pixbuf->has_alpha)
-               /* should be rgba */
-               art_pixbuf = art_pixbuf_new_rgb(pixels, w, h, rowstride);
-       else
-               art_pixbuf = art_pixbuf_new_rgb(pixels, w, h, rowstride);
+       g_return_val_if_fail (art_pixbuf != NULL, NULL);
 
-       art_pixbuf_free (pixbuf->art_pixbuf);
+       pixbuf = g_new (GdkPixbuf, 1);
+       pixbuf->ref_count = 1;
        pixbuf->art_pixbuf = art_pixbuf;
 
        return pixbuf;
index 7f4cece9cd35e88e399c2052dcd4e1a48cc395b4..5b4d695ca569f2785f87d5f688632d21b14106e5 100644 (file)
@@ -1,11 +1,10 @@
-/* GdkPixbuf library
+/* GdkPixbuf library - Main header file
  *
  * Copyright (C) 1999 The Free Software Foundation
  *
  * Authors: Mark Crichton <crichton@gimp.org>
  *          Miguel de Icaza <miguel@gnu.org>
  *          Federico Mena-Quintero <federico@gimp.org>
- *          Carsten Haitzler <raster@rasterman.com>
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public
@@ -36,32 +35,41 @@ extern "C" {
 
 \f
 
+/* GdkPixbuf structure */
+
 typedef struct _GdkPixbuf GdkPixbuf;
-typedef void (* GdkPixbufUnrefFunc) (GdkPixbuf *pixbuf);
 
 struct _GdkPixbuf {
+       /* Reference count */
        int ref_count;
+
+       /* Libart pixbuf */
        ArtPixBuf *art_pixbuf;
-       GdkPixbufUnrefFunc *unref_fn;
 };
 
 \f
 
-GdkPixbuf *gdk_pixbuf_load_image (const char *file);
-void gdk_pixbuf_save_image (const char *format_id, const char *file, ...);
-
-GdkPixbuf *gdk_pixbuf_new (ArtPixBuf *art_pixbuf, GdkPixbufUnrefFunc *unref_fn);
+/* Reference counting */
 
 void gdk_pixbuf_ref (GdkPixbuf *pixbuf);
 void gdk_pixbuf_unref (GdkPixbuf *pixbuf);
 
-GdkPixbuf *gdk_pixbuf_duplicate (const GdkPixbuf *pixbuf);
-GdkPixbuf *gdk_pixbuf_scale (const GdkPixbuf *pixbuf, gint w, gint h);
-GdkPixbuf *gdk_pixbuf_rotate (GdkPixbuf *pixbuf, gdouble angle);
+/* Wrap a libart pixbuf */
 
-void gdk_pixbuf_destroy (GdkPixbuf *pixbuf);
+GdkPixbuf *gdk_pixbuf_new_from_art_pixbuf (ArtPixBuf *art_pixbuf);
 
-GdkPixbuf *gdk_pixbuf_load_image_from_rgb_d (unsigned char *data, int rgb_width, int rgb_height);
+/* Simple loading */
+
+GdkPixbuf *gdk_pixbuf_new_from_file (const char *filename);
+GdkPixbuf *gdk_pixbuf_new_from_data (guchar *data, ArtPixFormat format, gboolean has_alpha,
+                                    int width, int height, int rowstride,
+                                    ArtDestroyNotify dfunc, gpointer dfunc_data);
+
+/* Transformations */
+#if 0
+GdkPixbuf *gdk_pixbuf_scale (const GdkPixbuf *pixbuf, gint w, gint h);
+GdkPixbuf *gdk_pixbuf_rotate (GdkPixbuf *pixbuf, gdouble angle);
+#endif
 
 \f
 
index 87d97931f409ea2d3f7c1828032f6c728392afa3..831c7ae440a467ed2a03a4b96d2a3fdb09a5d50f 100644 (file)
@@ -1,9 +1,10 @@
-/*
- * io-gif.c: GdkPixbuf I/O for GIF files.
- * ...second verse, same as the first...
+/* GdkPixbuf library - GIF image loader
  *
  * Copyright (C) 1999 Mark Crichton
- * Author: Mark Crichton <crichton@gimp.org>
+ * Copyright (C) 1999 The Free Software Foundation
+ *
+ * Authors: Mark Crichton <crichton@gimp.org>
+ *          Federico Mena-Quintero <federico@gimp.org>
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public
  * Library General Public License for more details.
  *
  * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Cambridge, MA 02139, USA.
- *
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
  */
 
 #include <config.h>
 #include <stdio.h>
 #include <glib.h>
-#include "gdk-pixbuf.h"
-#include "gdk-pixbuf-io.h"
 #include <gif_lib.h>
+#include "gdk-pixbuf.h"
+
+\f
+
+/* Destroy notification function for the libart pixbuf */
+static void
+free_buffer (gpointer user_data, gpointer data)
+{
+       free (data);
+}
 
 /* Shared library entry point */
 GdkPixbuf *
-image_load(FILE *f)
+image_load (FILE *f)
 {
        gint fn, is_trans = FALSE;
        gint done = 0;
        gint t_color = -1;
        gint w, h, i, j;
-       art_u8 *pixels, *tmpptr;
+       guchar *pixels, *tmpptr;
        GifFileType *gif;
        GifRowType *rows;
        GifRecordType rec;
        ColorMapObject *cmap;
-       int intoffset[] =
-       {0, 4, 2, 1};
-       int intjump[] =
-       {8, 8, 4, 2};
-
-       GdkPixbuf *pixbuf;
-       ArtPixBuf *art_pixbuf;
-
-       g_return_val_if_fail(f != NULL, NULL);
+       int intoffset[] = { 0, 4, 2, 1 };
+       int intjump[] = { 8, 8, 4, 2 };
 
-       fn = fileno(f);
-/*    lseek(fn, 0, 0);*/
-       gif = DGifOpenFileHandle(fn);
+       fn = fileno (f);
+       gif = DGifOpenFileHandle (fn);
 
        if (!gif) {
-               g_error("DGifOpenFilehandle FAILED");
-               PrintGifError();
+               g_warning ("DGifOpenFilehandle FAILED");
+               PrintGifError ();
                return NULL;
        }
-       /* Now we do the ungodly mess of loading a GIF image
-        * I used to remember when I liked this file format...
-        * of course, I still coded in assembler then.
-        * This comes from gdk_imlib, with some cleanups.
+
+       /* Now we do the ungodly mess of loading a GIF image I used to remember
+        * when I liked this file format...  of course, I still coded in
+        * assembler then.  This comes from gdk_imlib, with some cleanups.
         */
 
        do {
-               if (DGifGetRecordType(gif, &rec) == GIF_ERROR) {
-                       PrintGifError();
-                       rec = TERMINATE_RECORD_TYPE;
+               if (DGifGetRecordType (gif, &rec) == GIF_ERROR) {
+                       PrintGifError ();
+                       DGifCloseFile (gif);
+                       return NULL;
                }
-               if ((rec == IMAGE_DESC_RECORD_TYPE) && (!done)) {
-                       if (DGifGetImageDesc(gif) == GIF_ERROR) {
-                               PrintGifError();
-                               rec = TERMINATE_RECORD_TYPE;
+
+               if (rec == IMAGE_DESC_RECORD_TYPE && !done) {
+                       if (DGifGetImageDesc (gif) == GIF_ERROR) {
+                               PrintGifError ();
+                               DGifCloseFile (gif);
+                               return NULL;
                        }
+
+                       /* Note the careful use of malloc/calloc vs. g_malloc;
+                        * we want to fail gracefully if we run out of memory.
+                        */
+
                        w = gif->Image.Width;
                        h = gif->Image.Height;
-                       rows = g_malloc0(h * sizeof(GifRowType *));
+                       rows = calloc (sizeof (GifRowType *), h);
                        if (!rows) {
-                               DGifCloseFile(gif);
+                               DGifCloseFile (gif);
                                return NULL;
                        }
+
                        for (i = 0; i < h; i++) {
-                               rows[i] = g_malloc0(w * sizeof(GifPixelType));
+                               rows[i] = calloc (sizeof (GifPixelType), w);
                                if (!rows[i]) {
-                                       DGifCloseFile(gif);
-                                       for (i = 0; i < h; i++)
-                                               if (rows[i])
-                                                       g_free(rows[i]);
-                                       free(rows);
+                                       DGifCloseFile (gif);
+                                       for (j = 0; j < h; j++)
+                                               if (rows[j])
+                                                       free (rows[j]);
+
+                                       free (rows);
                                        return NULL;
                                }
                        }
-                       if (gif->Image.Interlace) {
+
+                       if (gif->Image.Interlace)
                                for (i = 0; i < 4; i++) {
                                        for (j = intoffset[i]; j < h; j += intjump[i])
-                                               DGifGetLine(gif, rows[j], w);
+                                               DGifGetLine (gif, rows[j], w);
                                }
-                       } else {
+                       else
                                for (i = 0; i < h; i++)
-                                       DGifGetLine(gif, rows[i], w);
-                       }
+                                       DGifGetLine (gif, rows[i], w);
+
                        done = 1;
                } else if (rec == EXTENSION_RECORD_TYPE) {
                        gint ext_code;
                        GifByteType *ext;
 
-                       DGifGetExtension(gif, &ext_code, &ext);
+                       DGifGetExtension (gif, &ext_code, &ext);
                        while (ext) {
-                               if ((ext_code == 0xf9) &&
-                                   (ext[1] & 1) && (t_color < 0)) {
+                               if ((ext_code == 0xf9) && (ext[1] & 1) && (t_color < 0)) {
                                        is_trans = TRUE;
                                        t_color = (gint) ext[4];
                                }
+
                                ext = NULL;
-                               DGifGetExtensionNext(gif, &ext);
+                               DGifGetExtensionNext (gif, &ext);
                        }
                }
-       }
-       while (rec != TERMINATE_RECORD_TYPE);
+       } while (rec != TERMINATE_RECORD_TYPE);
 
-       /* Ok, we're loaded, now to convert from indexed -> RGB
-        * with alpha if necessary
-        */
+       /* Ok, we're loaded, now to convert from indexed -> RGB with alpha if necessary */
 
        if (is_trans)
-               pixels = art_alloc(h * w * 4);
+               pixels = malloc (h * w * 4);
        else
-               pixels = art_alloc(h * w * 3);
+               pixels = malloc (h * w * 3);
+
        tmpptr = pixels;
 
-       if (!pixels)
+       if (!pixels) {
+               DGifCloseFile (gif);
+               for (i = 0; i < h; i++)
+                       if (rows[i])
+                               free (rows[i]);
+
+               free (rows);
                return NULL;
+       }
 
-       /* The meat of the transformation */
-       /* Get the right palette */
        cmap = (gif->Image.ColorMap ? gif->Image.ColorMap : gif->SColorMap);
 
-       /* Unindex the data, and pack it in RGB(A) order.
-        * Note for transparent GIFs, the alpha is set to 0
-        * for the transparent color, and 0xFF for everything else.
-        * I think that's right...
-        */
+       /* Unindex the data, and pack it in RGB(A) order */
 
        for (i = 0; i < h; i++) {
                for (j = 0; j < w; j++) {
                        tmpptr[0] = cmap->Colors[rows[i][j]].Red;
                        tmpptr[1] = cmap->Colors[rows[i][j]].Green;
                        tmpptr[2] = cmap->Colors[rows[i][j]].Blue;
-                       if (is_trans && (rows[i][j] == t_color))
-                               tmpptr[3] = 0;
-                       else
-                               tmpptr[3] = 0xFF;
-                       tmpptr += (is_trans ? 4 : 3);
-               }
-               g_free(rows[i]);
-       }
-       g_free(rows);
 
-       if (is_trans)
-               art_pixbuf = art_pixbuf_new_rgba(pixels, w, h, (w * 4));
-       else
-               art_pixbuf = art_pixbuf_new_rgb(pixels, w, h, (w * 3));
+                       if (is_trans) {
+                               if (rows[i][j] == t_color)
+                                       tmpptr[3] = 0;
+                               else
+                                       tmpptr[3] = 0xFF;
 
-       pixbuf = gdk_pixbuf_new (art_pixbuf, NULL);
+                               tmpptr += 4;
+                       } else
+                               tmpptr += 3;
+               }
+
+               free (rows[i]);
+       }
 
-       /* Ok, I'm anal...shoot me */
-       if (!pixbuf)
-               art_free(pixels);
+       free (rows);
+       DGifCloseFile (gif);
 
-       return pixbuf;
+       return gdk_pixbuf_new_from_data (pixels, ART_PIX_RGB, is_trans,
+                                        w, h, is_trans ? (w * 4) : (w * 3),
+                                        free_buffer, NULL);
 }
-
-image_save() {}
index 448e8c4fd1f2130785465d5d298fa30005a3132e..f35176a8cbaeb0194b6c98e6f9b1a2a8af4d605d 100644 (file)
-/*
-  io-jpeg.c: GdkPixbuf loader for jpeg files.
-
-  Based on io-jpeg from gdk_imlib, but not much.
-
-  This code is licensed under the Lesser GNU
-  General Public License, version 2.1.
-
-  Author:
-    Michael Zucchi <zucchi@zedzone.mmc.com.au>
-*/
+/* GdkPixbuf library - JPEG image loader
+ *
+ * Copyright (C) 1999 Michael Zucchi
+ * Copyright (C) 1999 The Free Software Foundation
+ *
+ * Authors: Michael Zucchi <zucchi@zedzone.mmc.com.au>
+ *          Federico Mena-Quintero <federico@gimp.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
 
 #include <config.h>
 #include <stdio.h>
-#include <glib.h>
 #include <setjmp.h>
-#include "gdk-pixbuf.h"
-/*#include "gdk-pixbuf-io.h"*/
 #include <jpeglib.h>
+#include "gdk-pixbuf.h"
+
+\f
 
 /* error handler data */
-struct iojpeg_JPEG_error_mgr {
+struct error_handler_data {
        struct jpeg_error_mgr pub;
        sigjmp_buf setjmp_buffer;
 };
 
 static void
-g_JPEGFatalErrorHandler(j_common_ptr cinfo)
+fatal_error_handler (j_common_ptr cinfo)
 {
        /* FIXME:
         * We should somehow signal what error occurred to the caller so the
         * caller can handle the error message */
-       struct iojpeg_JPEG_error_mgr *errmgr;
+       struct error_handler_data *errmgr;
 
-       errmgr = (struct iojpeg_JPEG_error_mgr *) cinfo->err;
-       cinfo->err->output_message(cinfo);
-       siglongjmp(errmgr->setjmp_buffer, 1);
+       errmgr = (struct error_handler_data *) cinfo->err;
+       cinfo->err->output_message (cinfo);
+       siglongjmp (errmgr->setjmp_buffer, 1);
        return;
 }
 
+/* Destroy notification function for the libart pixbuf */
+static void
+free_buffer (gpointer user_data, gpointer data)
+{
+       free (data);
+}
+
+/* Shared library entry point */
 GdkPixbuf *
-image_load(FILE *f)
+image_load (FILE *f)
 {
-       int w,h,i,j;
-       art_u8 *pixels=NULL, *dptr;
-       unsigned char *lines[4], /* Used to expand rows, via rec_outbuf_height, from
-                                   the header file:
-                                   "* Usually rec_outbuf_height will be 1 or 2, at most 4." */
-               **lptr;
+       int w, h, i, j;
+       guchar *pixels = NULL, *dptr;
+       guchar *lines[4]; /* Used to expand rows, via rec_outbuf_height, from the header file:
+                          * "* Usually rec_outbuf_height will be 1 or 2, at most 4."
+                          */
+       guchar **lptr;
        struct jpeg_decompress_struct cinfo;
-       struct iojpeg_JPEG_error_mgr jerr;
+       struct error_handler_data jerr;
        GdkPixbuf *pixbuf;
 
        /* setup error handler */
-       cinfo.err = jpeg_std_error(&(jerr.pub));
-       jerr.pub.error_exit = g_JPEGFatalErrorHandler;
+       cinfo.err = jpeg_std_error (&jerr.pub);
+       jerr.pub.error_exit = fatal_error_handler;
 
-       if (sigsetjmp(jerr.setjmp_buffer, 1)) {
+       if (sigsetjmp (jerr.setjmp_buffer, 1)) {
                /* Whoops there was a jpeg error */
-               if (pixels != NULL)
-                       art_free(pixels);
-               jpeg_destroy_decompress(&cinfo);
+               if (pixels)
+                       free (pixels);
+
+               jpeg_destroy_decompress (&cinfo);
                return NULL;
        }
 
        /* load header, setup */
-       jpeg_create_decompress(&cinfo);
-       jpeg_stdio_src(&cinfo, f);
-       jpeg_read_header(&cinfo, TRUE);
-       jpeg_start_decompress(&cinfo);
+       jpeg_create_decompress (&cinfo);
+       jpeg_stdio_src (&cinfo, f);
+       jpeg_read_header (&cinfo, TRUE);
+       jpeg_start_decompress (&cinfo);
        cinfo.do_fancy_upsampling = FALSE;
        cinfo.do_block_smoothing = FALSE;
 
        w = cinfo.output_width;
        h = cinfo.output_height;
-       g_print("w: %d h: %d\n", w, h);
 
-       pixels = art_alloc(h * w * 3);
-       if (pixels == NULL) {
-               jpeg_destroy_decompress(&cinfo);
+       pixels = malloc (h * w * 3);
+       if (!pixels) {
+               jpeg_destroy_decompress (&cinfo);
                return NULL;
        }
+
        dptr = pixels;
 
        /* decompress all the lines, a few at a time */
 
        while (cinfo.output_scanline < cinfo.output_height) {
                lptr = lines;
-               for (i=0;i<cinfo.rec_outbuf_height;i++) {
-                       *lptr++=dptr;
-                       dptr+=w*3;
+               for (i = 0; i < cinfo.rec_outbuf_height; i++) {
+                       *lptr++ = dptr;
+                       dptr += w * 3;
                }
-               jpeg_read_scanlines(&cinfo, lines, cinfo.rec_outbuf_height);
-               if (cinfo.output_components==1) {
-                       /* expand grey->colour */
-                       /* expand from the end of the memory down, so we can use
-                          the same buffer */
-                       for (i=cinfo.rec_outbuf_height-1;i>=0;i--) {
-                               unsigned char *from, *to;
-                               from = lines[i]+w-1;
-                               to = lines[i]+w*3-3;
-                               for (j=w-1;j>=0;j--) {
+
+               jpeg_read_scanlines (&cinfo, lines, cinfo.rec_outbuf_height);
+               if (cinfo.output_components == 1) {
+                       /* Expand grey->colour.  Expand from the end of the
+                        * memory down, so we can use the same buffer.
+                        */
+                       for (i = cinfo.rec_outbuf_height - 1; i >= 0; i--) {
+                               guchar *from, *to;
+
+                               from = lines[i] + w - 1;
+                               to = lines[i] + w * 3 - 3;
+                               for (j = w - 1; j >= 0; j--) {
                                        to[0] = from[0];
                                        to[1] = from[0];
                                        to[2] = from[0];
-                                       to-=3;
+                                       to -= 3;
                                        from--;
                                }
                        }
                }
        }
 
-       jpeg_finish_decompress(&cinfo);
-       jpeg_destroy_decompress(&cinfo);
+       jpeg_finish_decompress (&cinfo);
+       jpeg_destroy_decompress (&cinfo);
+
+       return gdk_pixbuf_new_from_data (pixels, ART_PIX_RGB, FALSE,
+                                        w, h, w * 3,
+                                        free_buffer, NULL);
 
-       /* finish off, create the pixbuf */
-       pixbuf = gdk_pixbuf_new (art_pixbuf_new_rgb (pixels, w, h, (w * 3)),
-                                NULL);
-       if (!pixbuf)
-               art_free (pixels);
-       
        return pixbuf;
 }
-
-/*
- * Local variables:
- * c-basic-offset: 8
- * End:
- */
index b1a3971a88ab22f7cfb039ae2f8030be7bb8c4ec..733a505826b589abe75bf51abfb8c64d65afa12f 100644 (file)
@@ -1,7 +1,10 @@
-/*
- * io-png.c: GdkPixbuf I/O for PNG files.
+/* GdkPixbuf library - JPEG image loader
+ *
  * Copyright (C) 1999 Mark Crichton
- * Author: Mark Crichton <crichton@gimp.org>
+ * Copyright (C) 1999 The Free Software Foundation
+ *
+ * Authors: Mark Crichton <crichton@gimp.org>
+ *          Federico Mena-Quintero <federico@gimp.org>
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public
  * Library General Public License for more details.
  *
  * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Cambridge, MA 02139, USA.
- *
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
  */
+
 #include <config.h>
 #include <stdio.h>
-#include <glib.h>
-#include "gdk-pixbuf.h"
-#include "gdk-pixbuf-io.h"
 #include <png.h>
+#include "gdk-pixbuf.h"
+
+\f
+
+/* Destroy notification function for the libart pixbuf */
+static void
+free_buffer (gpointer user_data, gpointer data)
+{
+       free (data);
+}
 
 /* Shared library entry point */
 GdkPixbuf *
@@ -31,17 +42,12 @@ image_load (FILE *f)
 {
        png_structp png_ptr;
        png_infop info_ptr, end_info;
-       gint i, depth, ctype, inttype, passes, bpp;             /* bpp = BYTES/pixel */
+       gint i, depth, ctype, inttype, passes, bpp;
        png_uint_32 w, h, x, y;
        png_bytepp rows;
-       art_u8 *pixels, *temp, *rowdata;
-       GdkPixbuf *pixbuf;
-       ArtPixBuf *art_pixbuf;
+       guchar *pixels, *temp, *rowdata;
 
-       g_return_val_if_fail (f != NULL, NULL);
-
-       png_ptr = png_create_read_struct (PNG_LIBPNG_VER_STRING,
-                                         NULL, NULL, NULL);
+       png_ptr = png_create_read_struct (PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
        if (!png_ptr)
                return NULL;
 
@@ -62,10 +68,9 @@ image_load (FILE *f)
                return NULL;
        }
 
-       png_init_io   (png_ptr, f);
+       png_init_io (png_ptr, f);
        png_read_info (png_ptr, info_ptr);
-       png_get_IHDR  (png_ptr, info_ptr, &w, &h, &depth, &ctype, &inttype,
-                      NULL, NULL);
+       png_get_IHDR (png_ptr, info_ptr, &w, &h, &depth, &ctype, &inttype, NULL, NULL);
 
        /* Ok, we want to work with 24 bit images.
         * However, PNG can vary depth per channel.
@@ -108,21 +113,30 @@ image_load (FILE *f)
        else
                bpp = 3;
 
-       pixels = art_alloc (w * h * bpp);
-       rows   = g_malloc  (h * sizeof(png_bytep));
+       pixels = malloc (w * h * bpp);
+       rows = malloc (h * sizeof (png_bytep));
 
        if (!pixels || !rows) {
+               if (pixels)
+                       free (pixels);
+
+               if (rows)
+                       free (rows);
+
                png_destroy_read_struct (&png_ptr, &info_ptr, &end_info);
                return NULL;
        }
+
        /* Icky code, but it has to be done... */
        for (i = 0; i < h; i++) {
-               if ((rows[i] = g_malloc (w * sizeof (art_u8) * bpp)) == NULL) {
+               if ((rows[i] = malloc (w * bpp)) == NULL) {
                        int n;
+
                        for (n = 0; n < i; n++)
-                               g_free (rows[i]);
-                       g_free (rows);
-                       art_free (pixels);
+                               free (rows[i]);
+
+                       free (rows);
+                       free (pixels);
                        png_destroy_read_struct (&png_ptr, &info_ptr, &end_info);
                        return NULL;
                }
@@ -137,105 +151,27 @@ image_load (FILE *f)
        temp = pixels;
 
        for (y = 0; y < h; y++) {
-               (png_bytep) rowdata = rows[y];
+               rowdata = rows[y];
                for (x = 0; x < w; x++) {
                        temp[0] = rowdata[(x * bpp)];
                        temp[1] = rowdata[(x * bpp) + 1];
                        temp[2] = rowdata[(x * bpp) + 2];
+
                        if (bpp == 4)
                                temp[3] = rowdata[(x * bpp) + 3];
+
                        temp += bpp;
                }
-               g_free (rows[y]);
+               free (rows[y]);
        }
-       g_free (rows);
+       free (rows);
 
        if (ctype & PNG_COLOR_MASK_ALPHA)
-               art_pixbuf = art_pixbuf_new_rgba (pixels, w, h, (w * 4));
+               return gdk_pixbuf_new_from_data (pixels, ART_PIX_RGB, TRUE,
+                                                w, h, w * 4,
+                                                free_buffer, NULL);
        else
-               art_pixbuf = art_pixbuf_new_rgb  (pixels, w, h, (w * 3));
-
-       pixbuf = gdk_pixbuf_new (art_pixbuf, NULL);
-
-       if (!pixbuf)
-               art_free (pixels);
-
-       return pixbuf;
-}
-
-int
-image_save (GdkPixbuf *pixbuf, FILE *file)
-{
-       png_structp png_ptr;
-       png_infop info_ptr;
-       art_u8 *data;
-       gint y, h, w;
-       png_bytepp row_ptr;
-       png_color_8 sig_bit;
-       gint type;
-
-       g_return_val_if_fail(file != NULL, FALSE);
-       g_return_val_if_fail(pixbuf != NULL, FALSE);
-
-       h = pixbuf->art_pixbuf->height;
-       w = pixbuf->art_pixbuf->width;
-
-       png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING,
-                                         NULL, NULL, NULL);
-       if (png_ptr == NULL) {
-               fclose(file);
-               return FALSE;
-       }
-
-       info_ptr = png_create_info_struct(png_ptr);
-       if (info_ptr == NULL) {
-               fclose(file);
-               png_destroy_write_struct(&png_ptr, (png_infopp) NULL);
-               return FALSE;
-       }
-
-       if (setjmp(png_ptr->jmpbuf)) {
-               fclose(file);
-               png_destroy_write_struct(&png_ptr, (png_infopp) NULL);
-               return FALSE;
-       }
-
-       png_init_io(png_ptr, file);
-       if (pixbuf->art_pixbuf->has_alpha) {
-               sig_bit.alpha = 8;
-               type = PNG_COLOR_TYPE_RGB_ALPHA;
-       } else {
-               sig_bit.alpha = 0;
-               type = PNG_COLOR_TYPE_RGB;
-       }
-
-       sig_bit.red = sig_bit.green = sig_bit.blue = 8;
-       png_set_IHDR(png_ptr, info_ptr, w, h, 8, type, PNG_INTERLACE_NONE,
-                    PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
-       png_set_sBIT(png_ptr, info_ptr, &sig_bit);
-       png_write_info(png_ptr, info_ptr);
-       png_set_shift(png_ptr, &sig_bit);
-       png_set_packing(png_ptr);
-
-       data = pixbuf->art_pixbuf->pixels;
-       row_ptr = g_new(png_byte *, h);
-
-       for (y = 0; y < h; y++)
-               row_ptr[y] = data + y * pixbuf->art_pixbuf->rowstride;
-#if 0
-       {
-               if (pixbuf->art_pixbuf->has_alpha)
-                       row_ptr[y] = data + (w * y * 4);
-               else
-                       row_ptr[y] = data + (w * y * 3);
-       }
-#endif
-
-       png_write_image(png_ptr, row_ptr);
-       g_free (row_ptr);
-
-       png_write_end(png_ptr, info_ptr);
-       png_destroy_write_struct(&png_ptr, (png_infopp) NULL);
-
-       return TRUE;
+               return gdk_pixbuf_new_from_data (pixels, ART_PIX_RGB, FALSE,
+                                                w, h, w * 3,
+                                                free_buffer, NULL);
 }
index 6fa935d7db5010e1b235601817c83652029bfdec..ea64b1b0e30f1aeda43da5238c6991d0b3c1a1a0 100644 (file)
@@ -1,7 +1,10 @@
-/*
- * io-tiff.c: GdkPixbuf I/O for TIFF files.
+/* GdkPixbuf library - JPEG image loader
+ *
  * Copyright (C) 1999 Mark Crichton
- * Author: Mark Crichton <crichton@gimp.org>
+ * Copyright (C) 1999 The Free Software Foundation
+ *
+ * Authors: Mark Crichton <crichton@gimp.org>
+ *          Federico Mena-Quintero <federico@gimp.org>
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public
  * Library General Public License for more details.
  *
  * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Cambridge, MA 02139, USA.
- *
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
  */
 
 /* Following code (almost) blatantly ripped from Imlib */
 
 #include <config.h>
 #include <stdio.h>
-#include <string.h>
-#include <glib.h>
 #include <tiffio.h>
-
 #include "gdk-pixbuf.h"
-/*#include "gdk-pixbuf-io.h" */
 
+\f
+
+/* Destroy notification function for the libart pixbuf */
+static void
+free_buffer (gpointer user_data, gpointer data)
+{
+       free (data);
+}
+
+/* Shared library entry point */
 GdkPixbuf *
 image_load (FILE *f)
 {
-       GdkPixbuf *pixbuf;
        TIFF *tiff;
-       art_u8 *pixels, *tmppix;
+       guchar *pixels, *tmppix;
        gint w, h, x, y, num_pixs, fd;
        uint32 *rast, *tmp_rast;
 
-       g_return_val_if_fail(f != NULL, NULL);
-
-       fd = fileno(f);
-       tiff = TIFFFdOpen(fd, "libpixbuf-tiff", "r");
+       fd = fileno (f);
+       tiff = TIFFFdOpen (fd, "libpixbuf-tiff", "r");
 
        if (!tiff)
                return NULL;
 
-       TIFFGetField(tiff, TIFFTAG_IMAGEWIDTH, &w);
-       TIFFGetField(tiff, TIFFTAG_IMAGELENGTH, &h);
+       TIFFGetField (tiff, TIFFTAG_IMAGEWIDTH, &w);
+       TIFFGetField (tiff, TIFFTAG_IMAGELENGTH, &h);
        num_pixs = w * h;
 
        /* Yes, it needs to be _TIFFMalloc... */
-       rast = (uint32 *) _TIFFmalloc(num_pixs * sizeof(uint32));
+       rast = (uint32 *) _TIFFmalloc (num_pixs * sizeof (uint32));
 
        if (!rast) {
-               TIFFClose(tiff);
+               TIFFClose (tiff);
                return NULL;
        }
 
-       if (TIFFReadRGBAImage(tiff, w, h, rast, 0)) {
-               pixels = art_alloc(num_pixs * 4);
+       if (TIFFReadRGBAImage (tiff, w, h, rast, 0)) {
+               pixels = malloc (num_pixs * 4);
                if (!pixels) {
-                       _TIFFfree(rast);
-                       TIFFClose(tiff);
+                       _TIFFfree (rast);
+                       TIFFClose (tiff);
                        return NULL;
                }
                tmppix = pixels;
@@ -76,23 +82,19 @@ image_load (FILE *f)
                         */
                        tmp_rast = rast + ((h - y - 1) * w);
                        for (x = 0; x < w; x++) {
-                               tmppix[0] = TIFFGetR(*tmp_rast);
-                               tmppix[1] = TIFFGetG(*tmp_rast);
-                               tmppix[2] = TIFFGetB(*tmp_rast);
-                               tmppix[3] = TIFFGetA(*tmp_rast);
+                               tmppix[0] = TIFFGetR (*tmp_rast);
+                               tmppix[1] = TIFFGetG (*tmp_rast);
+                               tmppix[2] = TIFFGetB (*tmp_rast);
+                               tmppix[3] = TIFFGetA (*tmp_rast);
                                tmp_rast++;
                                tmppix += 4;
                        }
                }
        }
-       _TIFFfree(rast);
-       TIFFClose(tiff);
-
-       pixbuf = gdk_pixbuf_new (art_pixbuf_new_rgba (pixels, w, h, (w * 4)),
-                                NULL);
-
-       if (!pixbuf)
-               art_free (pixels);
+       _TIFFfree (rast);
+       TIFFClose (tiff);
 
-       return pixbuf;
+       return gdk_pixbuf_new_from_data (pixels, ART_PIX_RGB, TRUE,
+                                        w, h, w * 4,
+                                        free_buffer, NULL);
 }
index d21fe0434ad3879c07d82d00271a2cc6f0405e5e..c6d74a4d31b407ac17a2d0deab252575486c7a76 100644 (file)
@@ -1,7 +1,10 @@
-/*
- * io-xpm.c: GdkPixbuf I/O for XPM files.
+/* GdkPixbuf library - JPEG image loader
+ *
  * Copyright (C) 1999 Mark Crichton
- * Author: Mark Crichton <crichton@gimp.org>
+ * Copyright (C) 1999 The Free Software Foundation
+ *
+ * Authors: Mark Crichton <crichton@gimp.org>
+ *          Federico Mena-Quintero <federico@gimp.org>
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public
  * Library General Public License for more details.
  *
  * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Cambridge, MA 02139, USA.
- *
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
  */
 
 #include <config.h>
 #include <stdio.h>
 #include <string.h>
 #include <glib.h>
-
-/* We need gdk.h since we might need to parse X color names */
 #include <gdk/gdk.h>
-
 #include "gdk-pixbuf.h"
-/*#include "gdk-pixbuf-io.h" */
+
+\f
 
 /* I have must have done something to deserve this.
  * XPM is such a crappy format to handle.
@@ -53,27 +54,28 @@ struct file_handle {
        FILE *infile;
        gchar *buffer;
        guint buffer_size;
-} file_handle;
+};
 
 struct mem_handle {
        gchar **data;
        int offset;
-} mem_handle;
+};
 
 static gint
-xpm_seek_string(FILE *infile, const gchar *str, gint skip_comments)
+xpm_seek_string (FILE *infile, const gchar *str, gint skip_comments)
 {
        char instr[1024];
 
-       while (!feof(infile)) {
-               fscanf(infile, "%1023s", instr);
-               if (skip_comments == TRUE && strcmp(instr, "/*") == 0) {
-                       fscanf(infile, "%1023s", instr);
-                       while (!feof(infile) && strcmp(instr, "*/") != 0)
-                               fscanf(infile, "%1023s", instr);
-                       fscanf(infile, "%1023s", instr);
+       while (!feof (infile)) {
+               fscanf (infile, "%1023s", instr);
+               if (skip_comments == TRUE && strcmp (instr, "/*") == 0) {
+                       fscanf (infile, "%1023s", instr);
+                       while (!feof (infile) && strcmp (instr, "*/") != 0)
+                               fscanf (infile, "%1023s", instr);
+                       fscanf (infile, "%1023s", instr);
                }
-               if (strcmp(instr, str) == 0)
+
+               if (strcmp (instr, str) == 0)
                        return TRUE;
        }
 
@@ -81,33 +83,34 @@ xpm_seek_string(FILE *infile, const gchar *str, gint skip_comments)
 }
 
 static gint
-xpm_seek_char(FILE *infile, gchar c)
+xpm_seek_char (FILE *infile, gchar c)
 {
        gint b, oldb;
 
-       while ((b = getc(infile)) != EOF) {
+       while ((b = getc (infile)) != EOF) {
                if (c != b && b == '/') {
-                       b = getc(infile);
+                       b = getc (infile);
                        if (b == EOF)
                                return FALSE;
+
                        else if (b == '*') {    /* we have a comment */
                                b = -1;
                                do {
                                        oldb = b;
-                                       b = getc(infile);
+                                       b = getc (infile);
                                        if (b == EOF)
                                                return FALSE;
-                               }
-                               while (!(oldb == '*' && b == '/'));
+                               } while (!(oldb == '*' && b == '/'));
                        }
                } else if (c == b)
                        return TRUE;
        }
+
        return FALSE;
 }
 
 static gint
-xpm_read_string(FILE *infile, gchar **buffer, guint *buffer_size)
+xpm_read_string (FILE *infile, gchar **buffer, guint *buffer_size)
 {
        gint c;
        guint cnt = 0, bufsiz, ret = FALSE;
@@ -116,28 +119,30 @@ xpm_read_string(FILE *infile, gchar **buffer, guint *buffer_size)
        buf = *buffer;
        bufsiz = *buffer_size;
        if (buf == NULL) {
-               bufsiz = 10 * sizeof(gchar);
-               buf = g_new(gchar, bufsiz);
+               bufsiz = 10 * sizeof (gchar);
+               buf = g_new (gchar, bufsiz);
        }
 
        do {
-               c = getc(infile);
+               c = getc (infile);
        } while (c != EOF && c != '"');
 
        if (c != '"')
                goto out;
 
-       while ((c = getc(infile)) != EOF) {
+       while ((c = getc (infile)) != EOF) {
                if (cnt == bufsiz) {
                        guint new_size = bufsiz * 2;
+
                        if (new_size > bufsiz)
                                bufsiz = new_size;
                        else
                                goto out;
 
-                       buf = (gchar *) g_realloc(buf, bufsiz);
+                       buf = g_realloc (buf, bufsiz);
                        buf[bufsiz - 1] = '\0';
                }
+
                if (c != '"')
                        buf[cnt++] = c;
                else {
@@ -155,7 +160,7 @@ xpm_read_string(FILE *infile, gchar **buffer, guint *buffer_size)
 }
 
 static gchar *
-xpm_skip_whitespaces(gchar *buffer)
+xpm_skip_whitespaces (gchar *buffer)
 {
        gint32 index = 0;
 
@@ -166,7 +171,7 @@ xpm_skip_whitespaces(gchar *buffer)
 }
 
 static gchar *
-xpm_skip_string(gchar *buffer)
+xpm_skip_string (gchar *buffer)
 {
        gint32 index = 0;
 
@@ -180,12 +185,13 @@ xpm_skip_string(gchar *buffer)
 #define MAX_COLOR_LEN 120
 
 static gchar *
-xpm_extract_color(gchar *buffer)
+xpm_extract_color (gchar *buffer)
 {
        gint counter, numnames;
        gchar *ptr = NULL, ch, temp[128];
        gchar color[MAX_COLOR_LEN], *retcol;
        gint space;
+
        counter = 0;
        while (ptr == NULL) {
                if (buffer[counter] == 'c') {
@@ -197,7 +203,7 @@ xpm_extract_color(gchar *buffer)
 
                counter++;
        }
-       ptr = xpm_skip_whitespaces(ptr);
+       ptr = xpm_skip_whitespaces (ptr);
 
        if (ptr[0] == 0)
                return NULL;
@@ -208,8 +214,8 @@ xpm_extract_color(gchar *buffer)
                        (ptr[counter] >= 'a' && ptr[counter] <= 'f') ||
                        (ptr[counter] >= 'A' && ptr[counter] <= 'F')))
                        counter++;
-               retcol = g_new(gchar, counter + 1);
-               strncpy(retcol, ptr, counter);
+               retcol = g_new (gchar, counter + 1);
+               strncpy (retcol, ptr, counter);
 
                retcol[counter] = 0;
 
@@ -220,60 +226,65 @@ xpm_extract_color(gchar *buffer)
 
        space = MAX_COLOR_LEN - 1;
        while (space > 0) {
-               sscanf(ptr, "%127s", temp);
+               sscanf (ptr, "%127s", temp);
 
                if (((gint) ptr[0] == 0) ||
-                   (strcmp("s", temp) == 0) || (strcmp("m", temp) == 0) ||
-                   (strcmp("g", temp) == 0) || (strcmp("g4", temp) == 0)) {
+                   (strcmp ("s", temp) == 0) || (strcmp ("m", temp) == 0) ||
+                   (strcmp ("g", temp) == 0) || (strcmp ("g4", temp) == 0))
                        break;
-               else {
+               else {
                        if (numnames > 0) {
                                space -= 1;
-                               strcat(color, " ");
+                               strcat (color, " ");
                        }
-                       strncat(color, temp, space);
-                       space -= MIN(space, strlen(temp));
-                       ptr = xpm_skip_string(ptr);
-                       ptr = xpm_skip_whitespaces(ptr);
+
+                       strncat (color, temp, space);
+                       space -= MIN (space, strlen (temp));
+                       ptr = xpm_skip_string (ptr);
+                       ptr = xpm_skip_whitespaces (ptr);
                        numnames++;
                }
        }
 
-       retcol = g_strdup(color);
+       retcol = g_strdup (color);
        return retcol;
 }
 
 /* (almost) direct copy from gdkpixmap.c... loads an XPM from a file */
 
 static gchar *
-file_buffer(enum buf_op op, gpointer handle)
+file_buffer (enum buf_op op, gpointer handle)
 {
        struct file_handle *h = handle;
 
        switch (op) {
        case op_header:
-               if (xpm_seek_string(h->infile, "XPM", FALSE) != TRUE)
+               if (xpm_seek_string (h->infile, "XPM", FALSE) != TRUE)
                        break;
 
-               if (xpm_seek_char(h->infile, '{') != TRUE)
+               if (xpm_seek_char (h->infile, '{') != TRUE)
                        break;
                /* Fall through to the next xpm_seek_char. */
 
        case op_cmap:
-               xpm_seek_char(h->infile, '"');
-               fseek(h->infile, -1, SEEK_CUR);
+               xpm_seek_char (h->infile, '"');
+               fseek (h->infile, -1, SEEK_CUR);
                /* Fall through to the xpm_read_string. */
 
        case op_body:
-               xpm_read_string(h->infile, &h->buffer, &h->buffer_size);
+               xpm_read_string (h->infile, &h->buffer, &h->buffer_size);
                return h->buffer;
+
+       default:
+               g_assert_not_reached ();
        }
-       return 0;
+
+       return NULL;
 }
 
 /* This reads from memory */
 static gchar *
-mem_buffer(enum buf_op op, gpointer handle)
+mem_buffer (enum buf_op op, gpointer handle)
 {
        struct mem_handle *h = handle;
        switch (op) {
@@ -282,14 +293,24 @@ mem_buffer(enum buf_op op, gpointer handle)
        case op_body:
                if (h->data[h->offset])
                        return h->data[h->offset++];
+
+       default:
+               g_assert_not_reached ();
        }
+
        return NULL;
 }
 
-/* This function does all the work. */
+/* Destroy notification function for the libart pixbuf */
+static void
+free_buffer (gpointer user_data, gpointer data)
+{
+       free (data);
+}
 
+/* This function does all the work. */
 static GdkPixbuf *
-_pixbuf_create_from_xpm(gchar * (*get_buf) (enum buf_op op, gpointer handle), gpointer handle)
+pixbuf_create_from_xpm (gchar * (*get_buf) (enum buf_op op, gpointer handle), gpointer handle)
 {
        gint w, h, n_col, cpp;
        gint cnt, xcnt, ycnt, wbytes, n, ns;
@@ -298,117 +319,108 @@ _pixbuf_create_from_xpm(gchar * (*get_buf) (enum buf_op op, gpointer handle), gp
        gchar pixel_str[32];
        GHashTable *color_hash;
        _XPMColor *colors, *color, *fallbackcolor;
-       art_u8 *pixels, *pixtmp;
-       GdkPixbuf *pixbuf;
-       ArtPixBuf *art_pixbuf;
+       guchar *pixels, *pixtmp;
 
        buffer = (*get_buf) (op_header, handle);
        if (!buffer) {
-               g_warning("No XPM header found");
+               g_warning ("No XPM header found");
                return NULL;
        }
-       sscanf(buffer, "%d %d %d %d", &w, &h, &n_col, &cpp);
+       sscanf (buffer, "%d %d %d %d", &w, &h, &n_col, &cpp);
        if (cpp >= 32) {
-               g_warning("XPM has more than 31 chars per pixel.");
+               g_warning ("XPM has more than 31 chars per pixel.");
                return NULL;
        }
+
        /* The hash is used for fast lookups of color from chars */
-       color_hash = g_hash_table_new(g_str_hash, g_str_equal);
+       color_hash = g_hash_table_new (g_str_hash, g_str_equal);
 
-       name_buf = g_new(gchar, n_col * (cpp + 1));
-       colors = g_new(_XPMColor, n_col);
+       name_buf = g_new (gchar, n_col * (cpp + 1));
+       colors = g_new (_XPMColor, n_col);
 
        for (cnt = 0; cnt < n_col; cnt++) {
                gchar *color_name;
 
                buffer = (*get_buf) (op_cmap, handle);
                if (!buffer) {
-                       g_warning("Can't load XPM colormap");
-                       g_hash_table_destroy(color_hash);
-                       g_free(name_buf);
-                       g_free(colors);
+                       g_warning ("Can't load XPM colormap");
+                       g_hash_table_destroy (color_hash);
+                       g_free (name_buf);
+                       g_free (colors);
                        return NULL;
                }
+
                color = &colors[cnt];
                color->color_string = &name_buf[cnt * (cpp + 1)];
-               strncpy(color->color_string, buffer, cpp);
+               strncpy (color->color_string, buffer, cpp);
                color->color_string[cpp] = 0;
-               buffer += strlen(color->color_string);
+               buffer += strlen (color->color_string);
                color->transparent = FALSE;
 
-               color_name = xpm_extract_color(buffer);
+               color_name = xpm_extract_color (buffer);
 
-               if ((color_name == NULL) || (g_strcasecmp(color_name, "None") == 0)
-                   || (gdk_color_parse(color_name, &color->color) == FALSE)) {
+               if ((color_name == NULL) || (g_strcasecmp (color_name, "None") == 0)
+                   || (gdk_color_parse (color_name, &color->color) == FALSE)) {
                        color->transparent = TRUE;
                        is_trans = TRUE;
                }
 
-               g_free(color_name);
-               g_hash_table_insert(color_hash, color->color_string, color);
+               g_free (color_name);
+               g_hash_table_insert (color_hash, color->color_string, color);
 
                if (cnt == 0)
                        fallbackcolor = color;
        }
 
        if (is_trans)
-               pixels = art_alloc(w * h * 4);
+               pixels = malloc (w * h * 4);
        else
-               pixels = art_alloc(w * h * 3);
+               pixels = malloc (w * h * 3);
 
        if (!pixels) {
-               g_warning("XPM: Cannot alloc ArtBuf");
-               g_hash_table_destroy(color_hash);
-               g_free(colors);
-               g_free(name_buf);
+               g_hash_table_destroy (color_hash);
+               g_free (colors);
+               g_free (name_buf);
                return NULL;
        }
+
        wbytes = w * cpp;
        pixtmp = pixels;
 
        for (ycnt = 0; ycnt < h; ycnt++) {
                buffer = (*get_buf) (op_body, handle);
-               if ((!buffer) || (strlen(buffer) < wbytes))
+               if ((!buffer) || (strlen (buffer) < wbytes))
                        continue;
+
                for (n = 0, cnt = 0, xcnt = 0; n < wbytes; n += cpp, xcnt++) {
-                       strncpy(pixel_str, &buffer[n], cpp);
+                       strncpy (pixel_str, &buffer[n], cpp);
                        pixel_str[cpp] = 0;
                        ns = 0;
 
-                       color = g_hash_table_lookup(color_hash, pixel_str);
+                       color = g_hash_table_lookup (color_hash, pixel_str);
 
                        /* Bad XPM...punt */
                        if (!color)
                                color = fallbackcolor;
 
-                       *pixtmp++ = (color->color.red)>>8;
-                       *pixtmp++ = (color->color.green)>>8;
-                       *pixtmp++ = (color->color.blue)>>8;
+                       *pixtmp++ = color->color.red >> 8;
+                       *pixtmp++ = color->color.green >> 8;
+                       *pixtmp++ = color->color.blue >> 8;
 
-                       if ((is_trans) && (color->transparent)) {
+                       if (is_trans && color->transparent)
                                *pixtmp++ = 0;
-                       } else if (is_trans) {
+                       else if (is_trans)
                                *pixtmp++ = 0xFF;
-                       }
                }
        }
-       g_hash_table_destroy(color_hash);
-       g_free(colors);
-       g_free(name_buf);
 
-       /* Ok, now stuff the GdkPixbuf with goodies */
+       g_hash_table_destroy (color_hash);
+       g_free (colors);
+       g_free (name_buf);
 
-       if (is_trans)
-               art_pixbuf = art_pixbuf_new_rgba(pixels, w, h, (w * 4));
-       else
-               art_pixbuf = art_pixbuf_new_rgb(pixels, w, h, (w * 3));
-
-       pixbuf = gdk_pixbuf_new (art_pixbuf, NULL);
-
-       if (!pixbuf)
-               art_free(pixels);
-
-       return pixbuf;
+       return gdk_pixbuf_new_from_data (pixels, ART_PIX_RGB, is_trans,
+                                        w, h, is_trans ? (w * 4) : (w * 3),
+                                        free_buffer, NULL);
 }
 
 /* Shared library entry point for file loading */
@@ -418,16 +430,10 @@ image_load (FILE *f)
        GdkPixbuf *pixbuf;
        struct file_handle h;
 
-       g_return_val_if_fail(f != NULL, NULL);
-
-       memset(&h, 0, sizeof(h));
+       memset (&h, 0, sizeof (h));
        h.infile = f;
-       pixbuf = _pixbuf_create_from_xpm(file_buffer, &h);
-       g_free(h.buffer);
+       pixbuf = pixbuf_create_from_xpm (file_buffer, &h);
+       g_free (h.buffer);
 
        return pixbuf;
 }
-
-image_save()
-{
-}